第一個Go的測試


Posted by Nacho on 2020-04-05

實作目標

學習寫第一個Go的單元測試的作法與了解它的使用方式。

開始

為什麼要寫測試?

  • 確保code執行過程中的正確性
  • 確保後續維護不會出錯
  • 以防edeg case的發生

準備程式執行檔與測試檔

在動手寫測試以前得先知道測試要寫在哪裡。一般在Go的環境中,測試檔案要另外寫在一個檔案並放在同一個路徑下,且命名要是程式執行檔名加 _test,例如我的程式實際執行在main.go,我的測試就會寫在main_test.go裡,並執行go test來測試。

# 專案結構
myproject/
- calc.go
- calc_test.go 
- main.go
- main_test.go

測試範例

這裡簡單在main.go寫一個回傳x+2結果的函式,並印出結果。接著在同一個目錄底下新增一個main_test.go,引入Go提供的testing套件,並寫一個test case。

# main.go
package main

import "fmt"

func Calculate(x int) (result int){
    result = x + 2
    return result
}

func main() {
    fmt.Println("main start!!")
    cal := Calculate(2)
    fmt.Println("cal:", cal)
}

---

# main_test.go
package main

import "testing"

func TestCalculate(t *testing.T) {
    if Calculate(2) != 4 { // 如果結果不為4,就噴出error裡的內容
        t.Error("Expected 2 + 2 to equal 4")
    }
}

由於,Calculate(2)結果必為4,所以通過所有測試。go test會幫忙執行所有_test.go的test case,如果想要看到詳細的測試輸出(verbose Test output),例如那些功能被執行、那些通過可以執行go test -v

nacho@ubuntu:~/go/simpleTest$ go test
PASS
ok      _/home/nacho/go/simpleTest       0.003s

此外,也可以設計Table driven testing來為不同範圍的輸入輸出值來進行測試,所以測試相同的函式不需要再做重複的copy&past,此外,設計多組測試也能降低Edge case跟bug在程式實際上線後才發現的情況。

# main_test.go

...

func TestTableCalculate(t * testing.T){
    var tests = []struct {
        input int
        expected int
    }{
        {2, 4},
        {-1, 1},
        {0, 2},
        {-5, -3},
        {9999, 10001},
    }   

    for _, test := range tests {
        if output := Calculate(test.input); output != test.expected {
            t.Error("Test Failed: input {}, expect {}, should receive: {}", test.input, test.expected, output)
        }
    }

}

詳細的測試輸出結果。

nacho@ubuntu:~/go/simpleTest$ go test -v
=== RUN   TestCalculate
--- PASS: TestCalculate (0.00s)
=== RUN   TestTableCalculate
--- PASS: TestTableCalculate (0.00s)
PASS
ok      _/home/nacho/go/simpleTest       0.008s

Go還提供另一個方便的參數-cover,讓開發者能評估測試的覆蓋率(coverage)。覆蓋率是一個參考,但高覆蓋率也代表這支程式完全freebug或功能完全運作正常。不需要為所有的功能撰寫詳盡的測試,以追求高覆蓋率,而要將重點放在於重要/核心的business logic上,並確保能cover到更多可能的Edge cases發生才能發揮測試做大的價值。

nacho@ubuntu:~/go/simpleTest$ go test -cover
PASS
coverage: 40.0% of statements
ok      _/home/nacho/go/simpleTest       0.003s

參考

https://tutorialedge.net/golang/intro-testing-in-go/


#Go testing







Related Posts

JS30 Day 29 筆記

JS30 Day 29 筆記

Secure Apache Using Certbot with Let's Encrypt on Ubuntu 20.04

Secure Apache Using Certbot with Let's Encrypt on Ubuntu 20.04

Web開發學習筆記21 — RESTful Routes

Web開發學習筆記21 — RESTful Routes


Comments